package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DerviceService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.DeviceDataVo;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class DerviceServiceImpl implements DerviceService {
    @Autowired
    private Client client;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private DeviceMapper deviceMapper;
    @Override
    public void syncProductList() {
        QueryProductListRequest query = new QueryProductListRequest();
        query.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        query.setCurrentPage(1);
        query.setPageSize(20);
        QueryProductListResponse response = null;
        try {
              response = client.queryProductList(query);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        if(!response.body.success){
            throw new RuntimeException(response.body.errorMessage);
        }
        String jsonStr = JSONUtil.toJsonStr(response.body.getData().getList().getProductInfo());
        redisTemplate.opsForValue().set("iot:all_product",jsonStr);
    }

    public List<ProductVo> getAllProducts(){
        String jsonStr = redisTemplate.opsForValue().get("iot:all_product");
        if(jsonStr == null || jsonStr.length() == 0){
            return null;
        }
        return JSONUtil.toList(jsonStr,ProductVo.class);
    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        Device bean = BeanUtil.toBean(deviceDto, Device.class);
        int count = deviceMapper.getProductCountByName(bean.getProductName());
        if(count > 0){
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        // 注册设备到iot
        RegisterDeviceRequest registerDevice = deviceDto.getRegisterDeviceRequest();
        registerDevice.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        RegisterDeviceResponse registerDeviceResponse  ;
        try {
            registerDeviceResponse = client.registerDevice(registerDevice);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        if(!registerDeviceResponse.body.getSuccess()){
            throw new RuntimeException(registerDeviceResponse.body.getErrorMessage());
        }
        bean.setIotId(registerDeviceResponse.body.getData().getIotId());
        // 获取产品名称
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.productKey = deviceDto.getProductKey();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        try {
            QueryProductResponse queryProductResponse = client.queryProduct(queryProductRequest);
            if(queryProductResponse.body.getSuccess()){
                bean.setProductName(queryProductResponse.body.getData().getProductName());
            }
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if(deviceDto.getLocationType().equals(0)){
            bean.setPhysicalLocationType(-1);
        }
        // 将设备数据插入到数据库
        try {
            deviceMapper.insertSelective(bean);

        } catch (Exception e) {
            // 如果插入失败，则将iot中的设备删除
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setDeviceName(bean.getDeviceName());
            deleteDeviceRequest.setIotId(bean.getIotId());
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            deleteDeviceRequest.setProductKey(bean.getProductKey());
            try {
                  client.deleteDevice(deleteDeviceRequest);
            } catch (Exception ex) {
                throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
            }
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);
        }
    }

    @Override
    public PageResponse<DeviceVo> selectPage(DevicePageQueryDto devicePageQueryDto) {
        PageHelper.startPage(devicePageQueryDto.getPageNum(),devicePageQueryDto.getPageSize());
        Page<DeviceVo> deviceVos = deviceMapper.selectPage(devicePageQueryDto);
        PageResponse<DeviceVo> deviceVoPageResponse = PageResponse.of(deviceVos, DeviceVo.class);
        return deviceVoPageResponse;
    }

    @Override
    public DeviceVo queryDeviceDetail(QueryDeviceDetailRequest request) {
        QueryDeviceDetailRequest queryDeviceDetailRequest = new QueryDeviceDetailRequest();
        queryDeviceDetailRequest.iotInstanceId = aliIoTConfigProperties.getIotInstanceId();
        queryDeviceDetailRequest.productKey = request.getProductKey();
        queryDeviceDetailRequest.iotId = request.getIotId();
        QueryDeviceDetailResponse queryDeviceDetailResponse;
        try {
              queryDeviceDetailResponse = client.queryDeviceDetail(queryDeviceDetailRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        DeviceVo deviceVo = deviceMapper.selectByIotId(request.getIotId());
        BeanUtil.copyProperties(queryDeviceDetailResponse.body.getData(),deviceVo);
        return deviceVo;
    }

    /**
     * 查询指定设备的物模型运行状态
     * @param request 查询设备的物模型运行状态请求模型
     * @return 物模型运行状态
     */
    @Override
    public ResponseResult queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse response;
        try {
            response = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        return ResponseResult.success(response.getBody().getData());
    }

    /**
     * 查看指定产品的已发布物模型中的功能定义详情
     *
     * @param request 查询已发布物模型请求模型
     * @return 已发布物模型中的功能定义详情
     */
    @Override
    public ResponseResult queryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryThingModelPublishedResponse response;
        try {
            response = client.queryThingModelPublished(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_THING_MODEL_PUBLISHED_ERROR);
        }
        return ResponseResult.success(response.getBody().getData());
    }

    /**
     * 更新设备
     *
     * @param deviceDto 更新设备请求模型
     */
    @Transactional
    @Override
    public void updateDevice(DeviceDto deviceDto) {
        //检验数据库是否存在设备
        Device dbDevice = deviceMapper.selectByPrimaryKey(deviceDto.getId());
        if (ObjectUtil.isEmpty(dbDevice)) {
            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
        }
        // 保存位置
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        //如果是随身设备，物理位置设为-1
        if (device.getLocationType().equals(0)) {
            device.setPhysicalLocationType(-1);
        }
        //更新数据库中设备信息
        try {
            deviceMapper.updateByPrimaryKeySelective(device);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);
        }
        //调用物联网接口，更新云服务设备信息
        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo nicknameInfo =
                BeanUtil.toBean(deviceDto, BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo.class);
        nicknameInfo.setIotId(dbDevice.getIotId());
        request.setDeviceNicknameInfo(Lists.newArrayList(nicknameInfo));
        BatchUpdateDeviceNicknameResponse response;
        try {
            response = client.batchUpdateDeviceNickname(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        // if (ObjectUtil.notEqual(Boolean.TRUE, response.getBody().getSuccess())) {
        if(!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
    }

    /**
     * 删除设备
     *
     * @param request 删除设备请求模型
     */
    @Override
    public void deleteDevice(DeleteDeviceRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        DeleteDeviceResponse response;
        try {
            response = client.deleteDevice(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        if (response.getBody().getSuccess()) {
            deviceMapper.deleteByIotId(request.getIotId());
            return;
        }
        throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
    }



}
